/**
 * Copyright (c) 2018 人人开源 All rights reserved.
 * <p>
 * https://www.renren.io
 * <p>
 * 版权所有，侵权必究！
 */

package com.evaluationSystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.evaluationSystem.config.R;
import com.evaluationSystem.config.RCode;
import com.evaluationSystem.entity.SecurityUser;
import com.evaluationSystem.entity.SysUserEntity;
import com.evaluationSystem.entity.UserDetail;
import com.evaluationSystem.entity.dto.SysDeptDTO;
import com.evaluationSystem.entity.dto.SysUserDTO;
import com.evaluationSystem.enums.SuperAdminEnum;
import com.evaluationSystem.mapper.SysUserDao;
import com.evaluationSystem.password.PasswordUtils;
import com.evaluationSystem.service.SysDeptService;
import com.evaluationSystem.service.SysRoleUserService;
import com.evaluationSystem.service.SysUserService;
import com.evaluationSystem.util.Constant;
import com.evaluationSystem.util.ConvertUtils;
import com.evaluationSystem.util.GeneratePassword;
import com.evaluationSystem.util.PageData;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.util.*;


/**
 * 系统用户
 *
 * @author Mark sunlightcs@gmail.com
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserDao, SysUserEntity> implements SysUserService {
    @Autowired
    private SysRoleUserService sysRoleUserService;
    @Autowired
    private SysDeptService sysDeptService;

    @Override
    public PageData<SysUserDTO> page(Map<String, Object> params) {
        //转换成like
        paramsToLike(params, "username");

        //分页
        IPage<SysUserEntity> page = getPage(params, Constant.CREATE_DATE, false);

        //普通管理员，只能查询所属部门及子部门的数据
        UserDetail user = SecurityUser.getUser();
        if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
            params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId()));
        }
        String roleId = (String) params.get("roleId");

        List<SysUserEntity> list = new ArrayList<>();
        if (StringUtils.isNotBlank(roleId)) {
            List<Long> idList = sysRoleUserService.selectByRoleId(Long.parseLong(roleId));
            if (!CollectionUtils.isEmpty(idList)) {
                LambdaQueryWrapper<SysUserEntity> wrapper = new LambdaQueryWrapper<>();
                wrapper.in(SysUserEntity::getId, idList);
                list = baseDao.selectList(wrapper);
            }
        } else {
            //查询
            list = baseDao.getList(params);
        }

        return getPageData(list, page.getTotal(), SysUserDTO.class);
    }

    @Override
    public List<SysUserDTO> list(Map<String, Object> params) {
        //普通管理员，只能查询所属部门及子部门的数据
        UserDetail user = SecurityUser.getUser();
        if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
            params.put("deptIdList", sysDeptService.getSubDeptIdList(user.getDeptId()));
        }

        List<SysUserEntity> entityList = baseDao.getList(params);

        return ConvertUtils.sourceToTarget(entityList, SysUserDTO.class);
    }

    @Override
    public SysUserDTO get(Long id) {
        SysUserEntity entity = baseDao.getById(id);

        return ConvertUtils.sourceToTarget(entity, SysUserDTO.class);
    }

    @Override
    public SysUserDTO getByUsername(String username) {
        SysUserEntity entity = baseDao.getByUsername(username);
        return ConvertUtils.sourceToTarget(entity, SysUserDTO.class);
    }

    @Override
    public SysUserDTO getByMobile(String mobile) {
        SysUserEntity entity = baseDao.getByMobile(mobile);
        return ConvertUtils.sourceToTarget(entity, SysUserDTO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysUserDTO dto) {
        SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class);

        try {
            String password2 = Base64.getEncoder().encodeToString(entity.getPassword().getBytes("UTF-8"));
            entity.setPassword2(password2);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //密码加密
        String password = PasswordUtils.encode(entity.getPassword());
        entity.setPassword(password);

        //保存用户
        entity.setSuperAdmin(SuperAdminEnum.NO.value());
        insert(entity);

        //保存角色用户关系
        sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUserDTO dto) {
        SysUserEntity entity = ConvertUtils.sourceToTarget(dto, SysUserEntity.class);

        //密码加密
        if (StringUtils.isBlank(dto.getPassword())) {
            entity.setPassword(null);
        } else {
            String password = PasswordUtils.encode(entity.getPassword());
            entity.setPassword(password);
        }

        //更新用户
        updateById(entity);

        //更新角色用户关系
        sysRoleUserService.saveOrUpdate(entity.getId(), dto.getRoleIdList());
    }

    @Override
    public void delete(Long[] ids) {
        //删除用户
        baseDao.deleteBatchIds(Arrays.asList(ids));

        //删除角色用户关系
        sysRoleUserService.deleteByUserIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePassword(String username, String newPassword) {
        newPassword = PasswordUtils.encode(newPassword);
        String password2 = null;

        try {
            password2 = Base64.getEncoder().encodeToString(newPassword.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        baseDao.updatePassword(username, newPassword, password2);
    }

    @Override
    public int getCountByDeptId(Long deptId) {
        return baseDao.getCountByDeptId(deptId);
    }

    @Override
    public List<Long> getUserIdListByDeptId(List<Long> deptIdList) {
        return baseDao.getUserIdListByDeptId(deptIdList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R insertBatch(List<SysUserEntity> entityList) {
        // 错误信息
        List<String> errorMessage = new ArrayList<>();

        List<SysDeptDTO> deptDTOList = sysDeptService.list(new HashMap<>());

        int totalCount = entityList.size();
        int errorCount = 0;
        int successCount = 0;

        for (int i = 0; i < entityList.size(); i++) {
            int lineNumber = i + 1;
            SysUserEntity sysUserEntity = entityList.get(i);

            int finalI = i;
            SysDeptDTO sysDeptDTO = deptDTOList.stream().filter(res -> res.getName().equals(entityList.get(finalI).getDeptName())).findFirst().orElse(null);
            if (sysDeptDTO == null) {
                errorCount++;
                errorMessage.add("第 " + lineNumber + " 行：部门名称不存在，忽略导入。");
                continue;
            } else {
                sysUserEntity.setDeptId(sysDeptDTO.getId());
            }

            try {
                sysUserEntity.setSuperAdmin(0);
                String passWordOne = GeneratePassword.getPassWordOne(8);

                try {
                    String password2 = Base64.getEncoder().encodeToString(passWordOne.getBytes("UTF-8"));
                    sysUserEntity.setPassword2(password2);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                //密码加密
                String password = PasswordUtils.encode(passWordOne);
                sysUserEntity.setPassword(password);

                baseDao.insert(sysUserEntity);
                successCount++;
            } catch (Exception e) {
                String message = e.getMessage().toLowerCase();
                errorCount++;
                // 通过索引名判断出错信息
                if (message.contains("uk_username")) {
                    errorMessage.add("第 " + lineNumber + " 行：用户名已经存在，忽略导入。");
                } else if (message.contains("uk_work_no")) {
                    errorMessage.add("第 " + lineNumber + " 行：工号已经存在，忽略导入。");
                } else if (message.contains("uk_mobile")) {
                    errorMessage.add("第 " + lineNumber + " 行：手机号已经存在，忽略导入。");
                } else if (message.contains("uk_email")) {
                    errorMessage.add("第 " + lineNumber + " 行：电子邮件已经存在，忽略导入。");
                } else {
                    errorMessage.add("第 " + lineNumber + " 行：未知错误，忽略导入");
                    log.error(e.getMessage(), e);
                }
            }
        }

        Map<String, Object> map = new HashMap<>();
        map.put("errorCount", errorCount);
        map.put("successCount", successCount);
        map.put("totalCount", totalCount);
        map.put("msg", "总上传行数：" + totalCount + "，已导入行数：" + successCount + "，错误行数：" + errorCount);
        map.put("details", errorMessage);

        if (errorCount > 0) {
            return R.of(RCode.CREATED, true, "文件导入成功，但有错误。", map);
        } else {
            return R.success();
        }

    }


}
